package com.account.config;


import com.account.common.constant.Constants;
import com.account.common.exception.BusinessException;
import com.account.common.exception.ValidateException;
import com.account.common.result.DataResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 全局系统异常
 */
@ControllerAdvice
public class GlobalExceptionHandler {

	Logger log = LoggerFactory.getLogger(this.getClass());

	/**
	 * 业务异常
	 * @param req
	 * @param e
	 * @return
	 * @throws Exception
	 */
	@ExceptionHandler(value = BusinessException.class)
	@ResponseBody
	public DataResult businessException(HttpServletRequest req, BusinessException e) throws Exception {
		log.error("错误码:" + e.getCode() + ",信息:" + e.getMessage(), e);
		return new DataResult(e.getCode(), e.getMessage());
	}

	/**
	 * 参数验证错误信息
	 * 
	 * @param req
	 * @param e
	 * @return
	 * @throws Exception
	 */
	@ExceptionHandler(value = MethodArgumentNotValidException.class)
	@ResponseBody
	public DataResult argsException(HttpServletRequest req, MethodArgumentNotValidException e)
			throws Exception {
		String message = Constants.FAILURE_PARAMS_ERROR;
//		List<InvalidArgument> invalidArguments = new ArrayList<InvalidArgument>();
//		for (FieldError error : e.getBindingResult().getFieldErrors()) {
//			InvalidArgument invalidArgument = new InvalidArgument();
//			invalidArgument.setErrorMessage(error.getDefaultMessage());
//			invalidArgument.setField(error.getField());
//			invalidArguments.add(invalidArgument);
//		}
		List<FieldError> errors = e.getBindingResult().getFieldErrors();
		if (errors.size() > 0) {
			message = errors.get(0).getDefaultMessage();
		}
		log.error(Constants.FAILURE_PARAMS_ERROR, e);
		DataResult result = new DataResult(Constants.FAILURE_PARAMS, message);
		result.setData(null);
		return result;
	}

	@ExceptionHandler(value = BindException.class)
	@ResponseBody
	public DataResult bindException(HttpServletRequest req, BindException e)
			throws Exception {
		String message = Constants.FAILURE_PARAMS_ERROR;
//		List<InvalidArgument> invalidArguments = new ArrayList<InvalidArgument>();
//		for (FieldError error : e.getBindingResult().getFieldErrors()) {
//			InvalidArgument invalidArgument = new InvalidArgument();
//			invalidArgument.setErrorMessage(error.getDefaultMessage());
//			invalidArgument.setField(error.getField());
//			invalidArguments.add(invalidArgument);
//		}
		List<FieldError> errors = e.getBindingResult().getFieldErrors();
		if (errors.size() > 0) {
			message = errors.get(0).getDefaultMessage();
		}
		log.error(Constants.FAILURE_PARAMS_ERROR, e);
		DataResult result = new DataResult(Constants.FAILURE_PARAMS, message);
		result.setData(null);
		return result;
	}

	@ExceptionHandler(value = HttpMessageNotReadableException.class)
	@ResponseBody
	public DataResult httpMessageNotReadableException(HttpServletRequest request, HttpMessageNotReadableException e)
			throws Exception {
		String message = e.getMessage();
		log.error(Constants.FAILURE_PARAMS_ERROR, e);
		DataResult result = new DataResult(Constants.FAILURE_PARAMS, Constants.FAILURE_PARAMS_ERROR);
		result.setData(null);
		return result;
	}


	@ExceptionHandler(value = ValidateException.class)
	@ResponseBody
	public DataResult validateException(HttpServletRequest request, ValidateException e)
			throws Exception {
		String message = e.getMessage();
		log.error(Constants.FAILURE_PARAMS_ERROR, e);
		DataResult result = new DataResult(Constants.FAILURE_PARAMS, message);
		result.setData(null);
		return result;
	}



	/**
	 * 系统异常
	 * 
	 * @param req
	 * @param e
	 * @return
	 * @throws Exception
	 */
	@ExceptionHandler(value = Exception.class)
	@ResponseBody
	public DataResult otherException(HttpServletRequest req, Exception e) throws Exception {
		DataResult result = new DataResult(Constants.FAILURE, Constants.FAILURE_SERVER_ERROR);
		result.setData(null);
		log.error(Constants.FAILURE_SERVER_ERROR, e);
		return result;
	}
}
